import pytoss.io
# TODO: should use the ReceiptManager to do IO, not raw output

_print_stderr = lambda msg: pytoss.io.write_stderr(msg + "\n")
_print_stdout = lambda msg: pytoss.io.write_stdout(msg + "\n")

class Virtualenv(object):
    
    path = property(lambda self: self.__path)
    
    def __init__(self, path):
        self.__path = path
        self.__modules = set()
        self.__connections = set()
        self.__dirty_connections = set()
    
    def _sync_with_connections(self):
        
        # we have the virtualenv at this point, make sure all modules are set up
        for connection in self.__dirty_connections:
            _print_stderr("synchronizing virtualenv libraries for connection %s" % str(connection))
            stream = connection.create_command_stream("%(path)s/bin/easy_install %(modules)s" % dict(
                path = self.__path,
                modules = " ".join(self.__modules)
            ))
            for stdout_line, stderr_line, stdout_byte, stderr_byte in stream:
                if stdout_line:
                    _print_stderr(stdout_line)
        self.__dirty_connections = set()
    
    def add_module(self, module_name):
        self.__modules.add(module_name)
        self.__dirty_connections = self.__dirty_connections.union( self.__connections )
        self._sync_with_connections()
    
    def add_connection(self, connection):
        
        # TODO: support Windows Connections as well
        # determine if the virtualenv is already set up
        try:
            checker_stream = connection.create_command_stream( "test -e %s" % self.__path )
            checker_stream.drain()
            virtualenv_path_exists = True
        except Exception, e:
            virtualenv_path_exists = False
        
        if not virtualenv_path_exists:

            # virtualenv did not exist, lets create it
            _print_stderr("virtualenv did not exist on connection, installing...")
            try:
                import virtualenv
            except ImportError:
                raise StandardError("you must install the 'virtualenv' module if you want to create virtual environments")
        
            # create the bootstrap script
            bootstrap_file = connection.open_tempfile()
            bootstrap_content = virtualenv.create_bootstrap_script("")
            bootstrap_file.write(bootstrap_content)
            bootstrap_file.close()
        
            # execute the bootstrap script
            _print_stderr("starting virtualenv install")
            command_stream = connection.create_command_stream("python %(bootstrap_path)s %(env_path)s" % dict(
                bootstrap_path = bootstrap_file.name,
                env_path = self.__path,
            ))
            try:
                _print_stderr("installing virtualenv")
                command_stream.drain()
            except Exception, e:
                raise StandardError("failed to install virtualenv '%s' (reason: %s)" % (self.__path, e.message))
        
        # we now have a valid virtualenv set up, be sure to track this guy
        _print_stderr("virtualenv installed")
        self.__connections.add(connection)
        self.__dirty_connections.add(connection)
        
        # synchronize all packages in this env
        self._sync_with_connections()
        